/*
 * Copyright 2004 original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jbfilter.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.jbfilter.core.FilterComponent;
import org.jbfilter.hibernate.FilterComponentHibernate;
import org.jbfilter.hibernate.FilterHandlerHibernate;
import org.jbfilter.hibernate.FilterHibernate;

/**
 * Supports only {@link FilterComponentHibernate}'s.
 * @author Marcus Adrian
 * @param <E>
 */
class _FilterHibernateImpl<E>
	extends
		_FilterImpl<E>
	implements
		FilterHibernate<E> {

	private SessionFactory sessionFactory;
	private HibernateTemplate template;

	// constructors
	_FilterHibernateImpl(SessionFactory sessionFactory) {
		this();
		setSessionFactory(sessionFactory);
	}
	_FilterHibernateImpl() {
		super();
		addClassRestriction(FilterComponentHibernate.class);
	}
	
	@Override
	public List<E> filter(final Class<E> clazz) {
		if (sessionFactory == null) {
			throw new NullPointerException("sessionFactory must be set when using this method.");
		}
		return template.execute(new HibernateCallback<List<E>>() {
			public List<E> doInHibernate(Session session) {
				return filter(clazz, session);
			}});
	}
	@Override
	public List<E> filter(Class<E> clazz, Session session) {
		Criteria criteria = session.createCriteria(clazz);
		for (FilterComponent<E> fc : getFilterComponents()) {
			if (!fc.isActive()) {
				continue;
			}
			Criterion criterion = ((FilterComponentHibernate<E>)fc).getCriterion();
			if (criterion != null) {
				criteria.add(criterion);
			}
		}
		@SuppressWarnings("unchecked")
		List<E> retour = criteria.list();
		return retour;
	}
	
	@Override
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
		template = new HibernateTemplate(sessionFactory);
	}
	@Override
	public FilterHandlerHibernate<E> newFilterHandler() {
		return new FilterHandlerHibernate<E>(this);
	}

}
